package com.gitee.wsl.db.dsl.query

import kotlin.jvm.JvmOverloads

class QBF private constructor() {
    private val qbfParameters = QBFParameters()

    object S {
        fun eq(field: String?, value: Any?): QBFParameters {
            return c().eq(field, value).build()
        }

        //QBF param calc
        fun eq(fields: Array<String?>, values: Array<String?>): QBFParameters {
            return c().eq(fields, values).build()
        }

        fun eqNot(field: String?, value: Any?): QBFParameters {
            return c().eqNot(field, value).build()
        }

        fun `in`(field: String?, vararg values:Any): QBFParameters {
            return c().`in`(field, values).build()
        }

        fun nul(field: String?): QBFParameters {
            return c().nul(field).build()
        }

        fun notNul(field: String?): QBFParameters {
            return c().notNul(field).build()
        }

        fun like(field: String?, value: String?): QBFParameters {
            return c().like(field, value).build()
        }

        fun le(field: String?, value: Any?): QBFParameters {
            return c().le(field, value).build()
        }

        fun leVeq(field: String?, value: Any?): QBFParameters {
            return c().leVeq(field, value).build()
        }

        fun ge(field: String?, value: Any?): QBFParameters {
            return c().ge(field, value).build()
        }

        fun geVeq(field: String?, value: Any?): QBFParameters {
            return c().geVeq(field, value).build()
        }
    }

    fun build(): QBFParameters {
        return qbfParameters
    }

    //QBF param calc
    fun eq(fields: Array<String?>, values: Array<String?>): QBF {
        for (i in fields.indices) qbfParameters.and(QBFParameter(fields[i]).equal(values[i]))
        return this
    }

    fun eq(field: String?, value: Any?): QBF {
        qbfParameters.and(QBFParameter(field).equal(value))
        return this
    }

    fun eqNot(field: String?, value: Any?): QBF {
        qbfParameters.and(QBFParameter(field).distanct(value))
        return this
    }

    fun `in`(field: String?, vararg values: Any): QBF {
        qbfParameters.and(QBFParameter(field).`in`(values))
        return this
    }

    fun nul(field: String?): QBF {
        qbfParameters.and(QBFParameter(field).isNull)
        return this
    }

    fun notNul(field: String?): QBF {
        qbfParameters.and(QBFParameter(field).isNotNull)
        return this
    }

    fun like(field: String?, value: String?): QBF {
        qbfParameters.and(QBFParameter(field).like(value))
        return this
    }

    fun le(field: String?, value: Any?): QBF {
        qbfParameters.and(QBFParameter(field).less(value))
        return this
    }

    fun leVeq(field: String?, value: Any?): QBF {
        qbfParameters.and(QBFParameter(field).lessOrEqual(value))
        return this
    }

    fun ge(field: String?, value: Any?): QBF {
        qbfParameters.and(QBFParameter(field).greater(value))
        return this
    }

    fun geVeq(field: String?, value: Any?): QBF {
        qbfParameters.and(QBFParameter(field).greaterOrEqual(value))
        return this
    }

    //QBF calc
    fun and(qbfParameter: QBFParameter): QBF {
        qbfParameters.and(qbfParameter)
        return this
    }

    fun and(otherParameters: QBFParameters): QBF {
        qbfParameters.and(otherParameters)
        return this
    }

    fun or(qbfParameter: QBFParameter): QBF {
        qbfParameters.or(qbfParameter)
        return this
    }

    fun or(others: QBFParameters): QBF {
        qbfParameters.or(others)
        return this
    }

    companion object {
        @JvmOverloads
        fun c(all: Boolean = false): QBF {
            val qbf = QBF()
            if (all) qbf.and(QBFParameter.ALL)
            return qbf
        }

        fun all(): QBFParameters {
            return c(true).build()
        }
    }
}
